package com.vshining.grame;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.validation.constraints.NotNull;
import java.net.URISyntaxException;

/**
 * Grails Controller 资源
 */
public class GrailsControllerResource implements ResourceElement, PermissionElement {
    private static final Logger log = LoggerFactory.getLogger(GrailsControllerResource.class);

    public static final String PERMISSION_TARGET = "controllers";
    public static final String RESOURCE_SCHEME = "grails:controller";
    private final String controllerName;
    private final String actionName;

    /**
     * @param controllerName grails controller name
     * @param actionName     参数：null代表ANY_ACTION；空字符串等价于“index”；
     */
    public GrailsControllerResource(@NotNull String controllerName, String actionName) {
        if (actionName != null && actionName.isEmpty())
            actionName = "index";
        log.trace("Create resource with controllerName:" + controllerName + " actionName:" + actionName);
        this.controllerName = controllerName;
        this.actionName = actionName;
    }

    public GrailsControllerResource(String uri) throws URISyntaxException {
        log.trace("Create resource with uri:" + uri);
        String[] s = uri.split(":");
        if (s.length != 3 || !uri.startsWith(RESOURCE_SCHEME)) {
            log.trace("Error uri:" + uri);
            throw new URISyntaxException(uri, "must be GRAILS_CONTROLLER_RESOURCE_SCHEME:/controllerName/actionName");
        }
        String[] c = s[2].split("/");
        if (c.length > 1) {
            this.controllerName = c[1];
        } else {
            throw new URISyntaxException(uri, "controller name can not be null");
        }
        log.trace("parse uri to controllerName:" + controllerName);
        if (c.length > 2) {
            this.actionName = c[2];
        } else if (uri.endsWith("/")) {
            this.actionName = "index";
        } else {
            this.actionName = null;
        }
        log.trace("parse uri to actionName:" + actionName);
    }

    @SuppressWarnings("unused")
    public String getControllerName() {
        log.trace("get controller name result:" + controllerName);
        return controllerName;
    }

    @SuppressWarnings("unused")
    public String getActionName() {
        log.trace("get controller name result:" + actionName);
        return actionName;
    }

    private String uri;

    @Override
    public String toURI() {
        log.trace("to uri begin...");
        if (uri == null) {
            StringBuilder uriBuilder = new StringBuilder();
            uriBuilder.append(RESOURCE_SCHEME);
            uriBuilder.append(":");
            uriBuilder.append("/");
            uriBuilder.append(controllerName);
            if (actionName != null) {
                uriBuilder.append("/");
                uriBuilder.append(actionName);
            }
            uri = uriBuilder.toString();
        }
        log.trace("to uri result:" + uri);
        return uri;
    }

    @Override
    public String toPermission() {
        log.trace("to permission begin...");
        StringBuilder permissionBuilder = new StringBuilder();
        permissionBuilder.append(PERMISSION_TARGET);
        permissionBuilder.append(":");
        permissionBuilder.append(controllerName);
        permissionBuilder.append(":");
        if (actionName == null) { // ANY_ACTION
            permissionBuilder.append("*");
        } else {
            permissionBuilder.append(actionName);
        }
        String permission = permissionBuilder.toString();
        log.trace("to permission result:" + permission);
        return permission;
    }

    @Override
    public String toString() {
        return toURI();
    }
}
